Managing Strings "When gold argues the cause, eloquence is impotent." Pubilius Syrus "Moral Sayings" 1st Century BC Introduction The GOLDSTR unit contains all the string management routines needed to support any sophisticated DOS application. The unit includes the following: Functions which make predefined adjustments to strings Support for character testing and conversion Functions which convert numbers to and from strings String encryption to protect your data String Adjustment Gold defines a user input with three basic variables: the keystroke or mouse action, the mouse X coordinate and the mouse Y coordinate. These three variables are defined in the KeyVars record as LastKey, LastX and LastY. Replicate(N : byte; Character:char): string; Constructs a string of repeated characters. This routine uses memory moves which are much faster than a for loop. PicFormat(Input,Picture:string;Pad:char;RightJustify:boolean): string; Returns a formatted string using the format characters '!@*#'. See chapter 16 for a complete discussion on formatting characters. TruncFormat(Input:string;Start,Len:byte; Pad:char):string; Truncates (or expands) a string beginning at a specified character position. If Start is greater than 1, character positions less than Start are truncated. If Len is greater than the remaining string, then the remaining string is padded to a length of Len using the Pad character. Squeeze(L:char;Str:string;Width:byte): string; Squeezes a string to the length defined by width, removing characters from the beginning or the end of the string if necessary. If 'L' is passed then the left portion of the string is retained, otherwise the right portion is retained. The returned string appears as if the string doesn't fit in the space allocated. This is accomplished by adding the squeeze character string. GoldStr defines a variable, StrVars.SqzChars which by default is a double dot string (..). FirstCapitalPos(Str:string): byte; Returns the position of the first capital letter contained in the passed string. A zero is returned if no capital letters are encountered. FirstCapital(Str:string): char; Returns the first capital letter encountered in the passed string. If no capital letters are encountered then a null character is returned. PadLeft(Str:string;Size:byte;ChPad:char):string; Left justifies the passed string, padding with ChPad, if necessary, to a length indicated by size. PadCenter(Str:string;Size:byte;ChPad:char):string; Centers the passed string within a string, padding with ChPad, if necessary, to a length indicated by size. PadRight(Str:string;Size:byte;ChPad:char):string; Right justifies the passed string, padding with ChPad, if necessary, to a length indicated by size. Pad(PadJust:gJust;Str:string;Size:byte;ChPad:char):string; If your application requires that the justification be determined at runtime then this is the routine for you. Pad incorporates all three by allowing you to specify the proper justification, Left, Right, or Center. TabSubStr(Source:string; TabCount:byte):string; This routine permits simple parsing of a delimited string using a single delimiter. It is used extensively within the toolkit itself. TabSubStr extracts the string immediately before the delimiter defined by TabCount. The GoldStr unit defines a global variable called StrVars.TabBreak which by default is the vertical split bar. An example of using TabSubStr follows: const UserStr = 'Silver|Bronze|Gold|Brass'; var SubStr: String; begin SubStr := TabSubStr(UserStr,3); { SubStr will now be 'Gold' } end; Last(N:byte;Str:string):string; Extracts the last part of a string beginning at a specified position. If N is greater than the length of the passed string, only the string is returned. First(N:byte;Str:string):string; Extracts the first part of a string. Beginning at position 1, First returns N number of characters. If N is greater than the length of the passed string, the entire string is returned. SetUpper(Str:string):string; Converts all alpha characters of the passed string to upper case. SetLower(Str:string):string; Converts all alpha characters of the passed string to lower case. SetProper(Str:string):string; Converts the first character of each word in the passed string to upper case while the remaining characters are converted to lower case. AdjCase(NewCase:gCase;Str:string):string; Returns an appropriately adjusted string. If your application requires that the case of words be modified during execution, AdjCase incorporates all three by allowing you to specify the proper case; Upper, Lower or Proper. The type gCase defines one other enumeration called Leave, which does nothing to the passed string. Just leaves it unaltered. OverType(N:byte;StrS,StrT:string):string; Places one string "on top of" another string and overlays the underlying characters. The function is passed three parameters; the character position in the target string to start the overtyping, the source string, and the target string. Strip(L,C:char;Str:string):string; Returns the string with a specific character C removed. The function is passed three parameters; a character to indicate which part of the string to strip, the character to strip, and the source string. The strip can be performed on the left of the string by specifying the L parameter with one of the following characters: 'L' - Removes the leftmost specified characters. 'R' - Removes the rightmost specified characters. 'B' - Removes the leftmost and rightmost characters. 'A' - Removes all specified characters. LastPos(C:char;Str:string):byte; Returns a byte indicating the position of the last occurrence of a character in a string. If the character is not found, a zero is returned. The function is passed two parameters; a character to search for, and the source string. PosAfter(C:char;Str:string;Start:byte):byte; Returns a byte indicating the position of the first occurrence of a character, starting from a specified position in the string. If the character is not found, or if Start is greater than the length of the passed string, a zero is returned. LastPosBefore(C:char;Str:string;Last:byte):byte; Returns a byte indicating the position of the last occurrence of a character, up to a specified part fo the string. The search begins at character 1 and continues through the character specified by Last. A zero is returned if the character is not found. NthPos(Nth:byte;St,Src:string): byte; Returns a byte indicating the position of the Nth occurrence of a substring in a string. A zero is returned if the substring is not found. PosWord(Wordno:byte;Str:string):byte; Returns the character position of a specified word in a string. WordCnt(Str:string):byte; Counts and returns the number of words contained in a string. ExtractWords(StartWord,NoWords:byte;Str:string):string; Beginning at a specified word, extracts a specific number of words from a string. String and Number Conversions The following three functions should be used to test whether a string can be successfully converted to its numerical equivalent: ValidInt(Str:string):boolean; Returns TRUE if the string can be converted to an integer. ValidHEXInt(Str:string):boolean; Returns TRUE if the source string represents a valid hexadecimal number. ValidReal(Str:string):boolean; Returns TRUE if the string can be converted to a real. The following functions enable string and number conversion: StrToInt(Str:string):integer; Converts a valid numeric string to an integer value. If the string does not represent an integer value, a zero is returned, and an error code of 1004 is assigned to LastStrError. StrToLong(Str:string):Longint; Converts a valid numeric string to a longint value. If the string does not represent a longint value, a zero is returned, and an error code of 1002 is assigned to LastStrError. IntToStr(Number:longint):string; Converts a whole number to its string equivalent. StrToReal(Str:string):extended; Converts a valid real string to a real. If the string does not represent a real value, a zero is returned, and an error code of 1003 is assigned to LastStrError. RealToStr(Number:extended;Decimals:byte):string; Converts a real to its string equivalent. If the number of decimal places is passed as FLOATING (a constant), the function will return only the significant digits. IntToHEXStr(Number:longint;Width:integer):string; Returns a string representing the value of a hexadecimal number. HEXStrToLong(Str:string):longint; Converts a hexadecimal string and returns a longint. If the string is not a valid hex number, a zero is returned, and an error code of 1002 is assigned to LastStrError. RealToSciStr(Number:extended; D:byte):string; Returns a real number converted to a scientific notation string. The second parameter identifies the number of decimal places. NthNumber(InStr:string;Nth:byte) : char; This function returns a number in character form. Gold searches InStr, counting each occurrence of a number character. When N number characters have been counted, the value of the Nth character is returned. For example, if the string '02/20/48' is passed, and the N parameter is passed as 5, the character '4' would be returned, i.e. the fifth number in the string has a value of 4. Character Evaluation and Case Conversion IsUpper(K:word): boolean; Returns TRUE if the value represented by K is an upper case character. IsLower(K:word): boolean; Returns TRUE if the value represented by K is a lower case character. IsDigit(K:word): boolean; Returns TRUE if the value represented by K is a digit ranging from 0 to 9. IsLetter(K:word): boolean; Returns TRUE if the value represented by K is an alpha character. IsPunctuation(K:word): boolean; Returns TRUE if the value represented by K is a punctuation character. GetUpCase(Ch:char):char; Converts the character represented by Ch to its upper case equivalent. GetLoCase(Ch:char):char; Converts the character represented by Ch to its lower case equivalent. CapitalWord(W:word):word; Converts the character represented by W to uppercase and returns the word value of the capital letter. String Encryption Data encryption has been the study of mathematicians and R & D teams since man determined that it was necessary to protect certain information. We would never attempt to compete with any of the highly complex methods of data encryption that are employed today. However, we have implemented an extremely simple but useful form of encryption. Each character of the passed string is encrypted using the XOR operator in conjunction with an encryption code. The variable StrVars.EncryptionCode, which is of type word, affects the content of the encrypted string. By default the encryption code is 134, but may be changed. If you are going to store the final encrypted strings in text files, it is important to keep the value of StrVars.EncryptionCode between 128 and 255. Values between 0 and 127 occasionally produce a Ctrl-Z or EOF character. This produces a premature end-of-file when the text file is being retrieved from disk. EnCode(Str: string): string; Converts the passed, readable string, to an unreadable string. DeCode(Str: string): string; Converts the passed, unreadable string, to a readable string. One valuable use of string encryption is to store encoded constants in a program, such as passwords. You can compare the user's input to the function call, DeCode(). The probability of someone locating and decoding your embedded password in the final, compiled program is, at best, slim to none. The encoded constants would be generated by another small utility program that you would write. Miscellaneous Listed below are some other string management functions that couldn't find a home anywhere else: CharCount(Ch:Char;Str:string):byte; Returns the total number of times Ch occurs in Str. WidestLine(Str:string):byte; Searches for the embedded line break character and returns the length of the longest line-element. The line break character is defined as a global variable, StrVars.LineBreak. Its default is the vertical split bar. LineCount(Str:string):byte; A bit different from the obvious appearance, LineCount returns the number of elements contained in a delimited string. LastStrError: integer; Returns the code of the last error generated by a GoldStr routine.